import { _window } from '@/global'
import { setRAFTimeout } from '../loash'

// 滚动懒加载中间件封装
export class RollingLazyLoad {
  private $el: HTMLElement
  private responseFn: Function | null = null // 注册加载事件
  private dealing: boolean = false
  private THROTTLE = 500
  private ListenerOptions: AddEventListenerOptions = {
    capture: _window.isMobile,
    passive: true,
  }

  constructor(targetEl: HTMLElement, callback?: Function) {
    if (!targetEl)
      throw new Error(`targetEl is ${targetEl}. Please make sure it is the correct element`)
    this.$el = targetEl
    this.responseFn = null
    if (this.isHtmldom()) {
      window.addEventListener('scoll', this.handleScroll.bind(this), this.ListenerOptions)
    }
    this.$el.addEventListener('scroll', this.handleScroll.bind(this), this.ListenerOptions)
    callback && callback()
  }

  private isHtmldom() {
    // 判断是不是 document.documentElement
    return this.$el === document.documentElement
  }

  // 注册滚动回调事件
  register(fn: Function) {
    this.responseFn = fn
  }

  // 是否屏幕已经布满
  async isFull(callback: Function): Promise<void> {
    return await new Promise(reslove => {
      // 留给屏幕渲染时间
      setRAFTimeout(() => {
        if (this.$el.clientHeight >= this.$el.scrollHeight) {
          callback()
        }
        reslove()
      }, this.THROTTLE)
    })
  }

  // 滚动逻辑处理
  handleScroll() {
    // console.log('e', e)
    if (this.dealing) return
    this.dealing = true
    setRAFTimeout(() => {
      // console.log('触发滚动事件')
      const consumeContain = this.$el.clientHeight + this.$el.scrollTop
      const totallContain = this.$el.scrollHeight * 0.9
      if (consumeContain >= totallContain) {
        this.responseFn && this.responseFn()
      }
      this.dealing = false
    }, this.THROTTLE)
  }

  // 注销滚动逻辑
  clear() {
    this.responseFn = null
    this.$el.removeEventListener('scroll', this.handleScroll.bind(this), this.ListenerOptions)
    if (this.isHtmldom()) {
      window.removeEventListener('scroll', this.handleScroll.bind(this), this.ListenerOptions)
    }
  }
}
